package com.sea.demo.shiro.common;

import com.sea.demo.shiro.exception.ShiroExceptionHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;

/**
 * @Author: 快乐在角落里
 * @Create: 2020/11/7 23:06
 * 前后端分离用 自定义Shiro会话管理器，默认shiro会从cookie中读取sessionId以此来维持会话
 * 自定义为从head中获取sessionId
 */
public class ShiroSessionManager extends DefaultWebSessionManager {

    private  final static Logger LOGGER = LogManager.getLogger(ShiroExceptionHandler.class);

    @Override
    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        Serializable sessionId = httpServletRequest.getHeader("token");
        if(sessionId != null){
            return sessionId;
        }else{
            sessionId = super.getSessionId(request, response);
        }
        return sessionId;
    }

    @Override
    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {

        Serializable sessionId = getSessionId(sessionKey);
        if (sessionId == null) {
            LOGGER.debug("Unable to resolve session ID from SessionKey [{}].  Returning null to indicate a session could not be found.", sessionKey);
            return null;
        }

        // *************** ADD START ****************
        ServletRequest request = null;
        if (WebUtils.isWeb(sessionKey)) {
            request = WebUtils.getRequest(sessionKey);
        }

        if (request != null) {
            Object s = request.getAttribute(sessionId.toString());
            if (s != null) {
                return (Session) s;
            }
        }
        // *************** ADD END ****************

        Session s = retrieveSessionFromDataSource(sessionId);
        if (s == null) {
            String msg = "Could not find session with ID [" + sessionId + "]";
            throw new UnknownSessionException(msg);
        }

        // *************** ADD START ****************
        if (request != null) {
            request.setAttribute(sessionId.toString(),s);
        }
        // *************** ADD END ****************

        return s;
    }
}
